js构造函数
前言:之前看过公司大神的代码,发现有很多构造函数,类似Java和C#的 new 方法来实例化一个对象,感觉很是受教,刚好最近在用es6,发现了用class来实现构造函数,于是总结了一下,也是回顾和提高的过程,由于本人也是前端小白,文章可能有很多错误,欢迎各位大神批评指正~~
传统ES5语法
// 常规方法一
function Persion(name, age) {
this.name = name; // this.key 赋值,则直接挂载到Persion实例
this.age = age;
this.getInfo = function() {
return {
name: this.name,
age: this.age
}
}
}
// 调用
var persion = new Persion('张三', 15);
// 此时的persion实例拥有name、age、getInfo()三个属性及方法
// 常规方法二
function Persion(name, age) {
var name = name;
var age = age;
var getInfo = function() {
return {
name: name,
age: age,
}
}
return { // 通过return将元素暴露给实例对象
name: name,
age: age,
getInfo: getInfo,
}
}
// 调用
var persion = new Persion('张三', 15);
// 此时的persion实例拥有name、age、getInfo()三个属性及方法
ES6
class Persion {
constructor(name, age) { // 一个类必须有constructor方法, 如果没有显式定义, 一个空的constructor方法会被默认添加。
this.name = name;
this.age = age;
}
getInfo() {
return {
name: this.name,
age: this.age,
}
}
}
// 调用
const persion = new Persion('张三', 17);
// 此时的persion实例拥有name、age、getInfo()三个属性及方法
注:ES6 class 声明构造函数会将所有内部元素暴露出来,但有的时候我们希望这些方法只在内部声明时使用,并不暴露给实例对象,在ES5中我们可以很方便的做到,如下栗子:
// ES5 实现私有方法
// 方案一
function Persion(name, age) {
this.name = name;
this.age = age;
var print = function(){
return name + '今年' + age + '岁了!';
}
this.setName = function(newName){
this.name = newName;
}
this.setAge = function(newAge){
this.age = newAge;
}
this.getInfo = function(){
{
name: name,
age: age,
}
}
this.printInfo = function(){
console.log(print());
}
}
// 实例化
var persion = newPersion('张三', 15);
// 方案二
function Persion(name, age) {
var name = name,
age = age;
// print作为私有方法,只在内部用于生成输出字符串,并不需要暴露到外部
var print = function(){
return name + '今年' + age + '岁了!';
}
var setName = function(newName){
name = newName;
}
var setAge = function(newAge){
age = newAge;
}
var getInfo = function(){
{
name: name,
age: age,
}
}
var printInfo = function(){
console.log(print());
}
return {
name: name,
age: age,
setName: setName,
setAge: setAge,
getInfo: getInfo,
printInfo: printInfo,
}
}
// 实例化
var persion = newPersion('张三', 15);
// 此时实例化的persion 将不会暴露出print方法,我个人更倾向于方案二的方法,可以清楚的看出哪些属性和方法需要暴露出来,也容易修改需要暴露的接口。
那么在ES6中我们要怎么实现私有的方法和属性呢?其实方法很多,但都很不友好,我只总结了三种,如果有什么好的方法欢迎大家给我留言,不胜感激:)
// 私有方法 变通方案
// 方案一 (其实并不算一个方法。。。)
class Persion {
constructor(name, age) {
this.name = name;
this.age = age;
}
_print() { // 通常以“_”开头命名的方法为内部私有方法
return name + '今年' + age + '岁了!';
}
setName(newName) {
this.name = newName;
}
setName(newAge) {
this.age= newAge;
}
printInfo() {
console.log(_print());
}
getInfo() {
return {
name: this.name,
name: this.age,
}
}
}
// 实例化
const persion = new Persion('张三', 15);
// 此时persion实例仍然能获取到_print方法,只能用来区分私用和公有方法而已;
// 方案二
// 注意若使用ES6箭头函数则this指向的是该方法本身,而非调用它的对象,
function _print() { // 外部声明_print 方法,在内部调用,此时_print 成为Persion类的私有方法
return this.name + '今年' + this.age + '岁了!';
}
class Persion {
constructor(name, age) {
this.name = name;
this.age = age;
}
setName(newName) {
this.name = newName;
}
setName(newAge) {
this.age= newAge;
}
printInfo() {
console.log(_print());
}
getInfo() {
return {
name: this.name,
name: this.age,
}
}
}
// 实例化
const persion = new Persion('张三', 15);
// 此时persion实例获取不到_print方法;
// 方案三
const print = Symbol('print'); // 声明一个Symbol值,用来做为私有方法的名字
class Persion {
constructor(name, age) {
this.name = name;
this.age = age;
}
setName(newName) {
this.name = newName;
}
setName(newAge) {
this.age= newAge;
}
[bar]() { // 将私有方法的名字命名为一个Symbol值。
return this.name + '今年' + this.age + '岁了!';
}
printInfo() {
console.log([bar]()); // 调用私有方法
}
getInfo() {
return {
name: this.name,
name: this.age,
}
}
}
// 实例化
const persion = new Persion('张三', 15);
// 此时persion实例获取不到[bar]方法;
# 追更
感谢 @黒之染 的评论, 构造函数还可以通过prototype来添加对象
栗子:
```
function Persion(name, age){
this.name = name,
this.age = age,
}
Persion.prototype.getInfo = function(){
return {
name: this.name,
age: this.name,
}
}
// 实例化
var persion = new Persion('张三');
// 此时实例化后的对象persion拥有getInfo()方法
persion.getInfo() // 输出{name: '张三'}
```
关于js构造函数的继承可以看一下我的下一篇文章js构造函数(继承方法及利弊)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。